/*
 * Copyright (C) 2010-2015 Nektra S.A., Buenos Aires, Argentina.
 * All rights reserved. Contact: http://www.nektra.com
 *
 *
 * This file is part of Deviare
 *
 *
 * Commercial License Usage
 * ------------------------
 * Licensees holding valid commercial Deviare licenses may use this file
 * in accordance with the commercial license agreement provided with the
 * Software or, alternatively, in accordance with the terms contained in
 * a written agreement between you and Nektra.  For licensing terms and
 * conditions see http://www.nektra.com/licensing/. Use the contact form
 * at http://www.nektra.com/contact/ for further information.
 *
 *
 * GNU General Public License Usage
 * --------------------------------
 * Alternatively, this file may be used under the terms of the GNU General
 * Public License version 3.0 as published by the Free Software Foundation
 * and appearing in the file LICENSE.GPL included in the packaging of this
 * file.  Please visit http://www.gnu.org/copyleft/gpl.html and review the
 * information to ensure the GNU General Public License version 3.0
 * requirements will be met.
 *
 **/

using System;
using System.Collections.Generic;
using CSharpConsole.Extensions;
using CSharpConsole.Model.Modules;
using CSharpConsole.Model.Process;
using CSharpConsole.Presenters;
using Nektra.Deviare2;
using System.Linq;

namespace CSharpConsole.Model.Hooks
{
    public class Hook
    {
        private readonly ISpyManager _spyManager;

        #region Properties

        public IntPtr Id { get; private set; }
        public string FunctionName { get; private set; }
        public string ModuleName { get; private set; }

        #endregion

        #region Instance Creation

        private Hook(IntPtr id, string moduleName, string functionName, ISpyManager spyManager)
        {
            Id = id;
            FunctionName = functionName;
            ModuleName = moduleName;
            _spyManager = spyManager;
        }

        public static Hook From(NktHook nktHook, ISpyManager aSyManager)
        {
            return new Hook(nktHook.Id, nktHook.ModuleName(), nktHook.FunctionNameWithoutModule(), aSyManager);
        }

        #endregion

        #region Equality Members

        public bool Equals(Hook other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return other.Id.Equals(Id);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (Hook)) return false;
            return Equals((Hook) obj);
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }

        #endregion

        public bool IsActiveOn(IRunningProcess aProcess)
        {
            return _spyManager.IsHookActiveOn(this, aProcess);
        }

        public bool IsAppliedOn(Module aModule, IEnumerable<Function> functions)
        {
            return aModule.HasName(ModuleName) && functions.Any(f => f.HasName(FunctionName));
        }
    }
}